import { getObjType } from '../utils/util';
import { isRealNull, isRealNum, valueIsError } from './validate';
import { datenum_local, genarate, parseDate, update } from './format';
import server from '../controllers/server';
import luckysheetConfigsetting from '../controllers/luckysheetConfigsetting';
import Store from '../store/index';
import { deepCopy } from '../utils/chartUtil';
import { isNil, isString } from 'lodash';
import { isdatetime } from './datecontroll';
import numeral from 'numeral';
import Decimal from 'decimal.js';

// 仅用于初始化阶段的 setcellvalue;
function initsetcellValue (r, c, d, v) {
    if (d == null) {
        d = Store.flowdata;
    }
    // 若采用深拷贝，初始化时的单元格属性丢失
    // let cell = $.extend(true, {}, d[r][c]);
    let cell = d[r][c];
    let vupdate;
    if (getObjType(v) == "object") {
        if (cell == null) {
            cell = v;
        } else {
            if (v.f != null) {
                cell.f = v.f;
            } else if (cell.hasOwnProperty('f')) {
                delete cell.f;
            }

            if (v.spl != null) {
                cell.spl = v.spl;
            }

            if (v.ct != null) {
                cell.ct = v.ct;
            }
            cell.df = v.df;
        }

        if (getObjType(v.v) == "object") {
            vupdate = v.v.v;
        } else {
            vupdate = v.v;
        }
    } else {
        vupdate = v;
    }
    if (cell && cell.ct && cell.ct.t === 'inlineStr' && cell.ct.s) {
        d[r][c] = cell;
        return;
    }
    if (isNil(vupdate)) {
        if (getObjType(cell) == "object") {
            delete cell.m;
            delete cell.v;
        } else {
            cell = null;
        }

        d[r][c] = cell;

        return;
    }
    let vupdateStr = vupdate.toString();

    if (vupdateStr.includes('\r\n') || vupdateStr.includes('\n')) {
        cell.v = vupdateStr;

        if (cell.ct && cell.ct.t === 'inlineStr' && cell.ct.s) {
            if (!(vupdateStr === cell.ct.s.map((ctv) => ctv.v).join('')))  {
                cell.ct.s = [
                    {
                        "v": vupdateStr
                    }
                ];
            }
        } else {
            let fa = "General";
            if (cell.ct && cell.ct.fa) fa = cell.ct.fa;
            cell.ct = {
                fa,
                "t": "inlineStr",
                "s": [
                    {
                        "v": vupdateStr
                    }
                ]
            };
        }

        delete cell.m;
        d[r][c] = cell;
        return;
    }
    if (cell.ct != null && cell.ct.t == "s") {
        if (!cell.editRender) {
            cell.m = vupdateStr;
        }
        cell.v = vupdate;
    } else if (cell.ct != null && cell.ct.fa != null && cell.ct.fa != "General") {
        if (isRealNum(vupdate)) {
            vupdate = parseFloat(vupdate);
        }

        let mask = update(cell.ct.fa, vupdate);
        if (mask === vupdate) { // 若原来单元格格式 应用不了 要更新的值，则获取更新值的 格式
            cell.m = vupdateStr;
            // if (cell.m !== '#待查询') cell.ct = mask[1];
            cell.v = vupdate;
        } else {
            cell.m = mask.toString();
            cell.v = vupdate;
        }
    } else {
        if (isRealNum(vupdate) && !/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[12])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i.test(vupdate)) {
            vupdate = parseFloat(vupdate);
            cell.v = vupdate;   /* 备注：如果使用parseFloat，1.1111111111111111会转换为1.1111111111111112 ? */

            cell.ct = { "fa": "General", "t": "n" };
            if (cell.v == Infinity || cell.v == -Infinity) {
                cell.m = cell.v.toString();
            } else {
                let mask = genarate(cell.v);
                cell.m = mask[0].toString();
            }
        } else {
            let mask = genarate(vupdate);
            cell.m = mask[0].toString();
            cell.ct = mask[1];
            cell.v = mask[2];
        }
    }
    d[r][c] = cell;
}

function isPercentageString (str) {
    // 使用正则表达式检查字符串是否以百分比符号结尾
    // 例如：'25%' 或 '-10.5%' 是有效的百分比字符串
    const percentagePattern = /^[-+]?[0-9]*\.?[0-9]+%$/;
    return percentagePattern.test(str);
}
// Set cell value
function setcellvalue (r, c, d, v) {
    if (d == null) {
        d = Store.flowdata;
    }
    // 若采用深拷贝，初始化时的单元格属性丢失
    // let cell = $.extend(true, {}, d[r][c]);
    // 判断是不是frozen对象
    let cell = Object.isFrozen(d[r][c]) ? deepCopy(d[r][c]) : d[r][c];

    let vupdate;
    if (getObjType(v) == "object") {
        if (cell == null) {
            cell = v;
        } else {
            if (v.f != null) {
                cell.f = v.f;
            } else if (cell.hasOwnProperty('f')) {
                delete cell.f;
            }

            if (v.spl != null) {
                cell.spl = v.spl;
            }

            if (v.ct != null) {
                cell.ct = v.ct;
            }
            cell.df = v.df;
        }

        if (getObjType(v.v) == "object") {
            vupdate = v.v.v;
        } else {
            vupdate = v.v;
        }
    } else {
        vupdate = v;
    }
    if (cell && cell.editRender) {
        d[r][c] = cell;
        return;
    }
    if (cell && cell.ct && cell.ct.t === 'inlineStr' && cell.ct.s) {
        d[r][c] = cell;
        return;
    }
    if (isNil(vupdate)) {
        if (getObjType(cell) == "object") {
            delete cell.m;
            delete cell.v;
        } else {
            cell = null;
        }

        d[r][c] = cell;

        return;
    }

    // 1.为null
    // 2.数据透视表的数据，flowdata的每个数据可能为字符串，结果就是cell == v == 一个字符串或者数字数据
    if (isRealNull(cell) || (getObjType(cell) === 'string' || getObjType(cell) === 'number') && cell === v) {
        cell = {};
    }

    let vupdateStr = vupdate.toString();
    if (vupdateStr.includes('\r\n') || vupdateStr.includes('\n')) {
        cell.v = vupdateStr;

        if (cell.ct && cell.ct.t === 'inlineStr' && cell.ct.s) {
            if (!(vupdateStr === cell.ct.s.map((ctv) => ctv.v).join('')))  {
                cell.ct.s = [
                    {
                        "v": vupdateStr
                    }
                ];
            }
        } else {
            let fa = "General";
            if (cell.ct && cell.ct.fa) fa = cell.ct.fa;
            cell.ct = {
                fa,
                "t": "inlineStr",
                "s": [
                    {
                        "v": vupdateStr
                    }
                ]
            };
        }
        delete cell.m;
        d[r][c] = cell;
        return;
    }
    if (vupdateStr.substr(0, 1) == "'") {
        cell.m = vupdateStr.substr(1);
        cell.ct = { "fa": "@", "t": "s" };
        cell.v = vupdateStr.substr(1);
        cell.qp = 1;
    } else if (cell.qp == 1) {
        cell.m = vupdateStr;
        cell.ct = { "fa": "@", "t": "s" };
        cell.v = vupdateStr;
    } else if (vupdateStr.toUpperCase() === "TRUE") {
        cell.m = "TRUE";
        cell.ct = { "fa": "General", "t": "b" };
        cell.v = true;
    } else if (vupdateStr.toUpperCase() === "FALSE") {
        cell.m = "FALSE";
        cell.ct = { "fa": "General", "t": "b" };
        cell.v = false;
    } else if (cell.ct != null && cell.ct.fa != null && cell.ct.fa != "@" && vupdateStr.substr(-1) === "%" && isRealNum(vupdateStr.substring(0, vupdateStr.length - 1)) && !cell.ct.fa.includes('%')) {
        cell.ct = { fa: "0%", t: "n" };
        cell.v = new Decimal(vupdateStr.substring(0, vupdateStr.length - 1)).div(100).toNumber();
        cell.m = vupdate;
    } else if (valueIsError(vupdate)) {
        cell.m = vupdateStr;
        // cell.ct = { "fa": "General", "t": "e" };
        if (cell.ct != null) {
            cell.ct.t = "e";
        } else {
            cell.ct = { "fa": "General", "t": "e" };
        }
        cell.v = vupdate;
    } else {
        if (cell.ct != null && (cell.ct.t == 's')) {
            if (!cell.editRender) {
                cell.m = vupdateStr;
            }
            cell.v = vupdate;
        } else if (cell.ct != null && cell.ct.fa != null && cell.ct.fa != "General") {
            if (isRealNum(vupdate)) {
                vupdate = parseFloat(vupdate);
            }
            let mv = vupdate;
            if (isString(vupdate) && isPercentageString(vupdate)) {
                let decimalValue = new Decimal(vupdate.replace('%', ''));

                // 将小数值除以 100，以得到小数表示
                decimalValue = decimalValue.div(100); // 第二个参数指定小数点后的精度
                mv = decimalValue.toNumber();
            }
            let mask = update(cell.ct.fa, mv);

            if (mask === vupdate && cell.ct.fa !== '@') { // 若原来单元格格式 应用不了 要更新的值，则获取更新值的 格式
                if (isdatetime(mask.toString()) && cell.ct.fa !== '@') {
                    let v = datenum_local(parseDate(mask.toString().replace(/-/g, "/")));
                    cell.v = v;
                    mask = update(cell.ct.fa, v);
                    if (mask === v) {
                        cell.m = v.toString();
                    } else {
                        cell.m = mask.toString();
                    }
                } else {
                    cell.m = vupdate.toString();
                    // if (cell.m !== '#待查询') cell.ct = mask[1];
                    cell.v = mv;
                }
            } else {
                cell.m = mask.toString();
                cell.v = mv;
            }
        } else {
            if (isRealNum(vupdate) && !/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[12])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i.test(vupdate)) {
                vupdate = parseFloat(vupdate);
                cell.v = vupdate;   /* 备注：如果使用parseFloat，1.1111111111111111会转换为1.1111111111111112 ? */

                cell.ct = { "fa": "General", "t": "n" };
                cell.m = cell.v.toString();
            } else {
                let mask = genarate(vupdate);
                cell.m = mask[0].toString();
                cell.ct = mask[1];
                cell.v = mask[2];
            }
        }
    }

    if (!server.allowUpdate && !luckysheetConfigsetting.pointEdit) {
        if (cell.ct != null && /^(w|W)((0?)|(0\.0+))$/.test(cell.ct.fa) == false && cell.ct.t == "n" && cell.v != null && parseInt(cell.v).toString().length > 4) {
            let autoFormatw = luckysheetConfigsetting.autoFormatw.toString().toUpperCase();
            let accuracy = luckysheetConfigsetting.accuracy;

            let sfmt = setAccuracy(autoFormatw, accuracy);

            if (sfmt != "General") {
                cell.ct.fa = sfmt;
                cell.m = update(sfmt, cell.v);
            }
        }
    }
    if (Store.syncOrigin.flag && cell) {
        cell.ov = cell.v;
        if (cell.ct && cell.ct.s && cell.ct.s.length) {
            let concatV = cell.ct.s.map((s) => s.v).join('');
            cell.ov = concatV;
        }
        cell.of = cell.f;
    }
    d[r][c] = cell;
}

// new runze 根据亿万格式autoFormatw和精确度accuracy 转换成 w/w0/w0.00 or 0/0.0格式
function setAccuracy (autoFormatw, accuracy) {
    let acc = "0.";
    let fmt;

    if (autoFormatw == "TRUE") {
        if (accuracy == undefined) {
            return "w";
        } else {
            let alength = parseInt(accuracy);

            if (alength == 0) {
                return "w0";
            } else {
                acc = "w0.";

                for (let i = 0; i < alength; i++) {
                    acc += "0";
                }

                fmt = acc;
            }
        }
    } else {
        if (accuracy == undefined) {
            return "General";
        } else {
            let alength = parseInt(accuracy);

            if (alength == 0) {
                return "0";
            } else {
                for (let i = 0; i < alength; i++) {
                    acc += "0";
                }

                fmt = acc;
            }
        }
    }

    return fmt.toString();
}

export {
    setcellvalue,
    setAccuracy,
    initsetcellValue
};
